﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using IssuesClient.IssueServiceReference;
using System.Collections.ObjectModel;

namespace IssuesClient
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private IssueServiceClient serviceClient;
        User connectedUser;

        public enum LoginButtonStatus {Connect, Disconnect};
        public enum EditButtonStatus { Edit, Create };

        #region Properties
        private ObservableCollection<Issue> issueList;
       
        public User ConnectedUser
        {
            get
            {
                return this.connectedUser;
            }
            set
            {
                this.connectedUser = value;
            }
        }
        
        public ObservableCollection<Issue> IssueList
        {
            get
            {
                return this.issueList;
            }
            set
            {
                this.issueList = value;
            }
        }

        public IssueServiceClient ServiceClient
        {
            get
            {
                return this.serviceClient;
            }
            set
            {
                this.serviceClient = value;
            }
        }
        #endregion

        #region Constructor

        public Window1()
        {
            InitializeComponent();
            this.issueList = new ObservableCollection<Issue>();

            this.serviceClient = new IssueServiceClient("WSHttpBinding_IIssueService");

            
        }

        #endregion

        #region Login - Register

        /// <summary>
        /// Method that will be used when user clicks login. The methods logs in the user if no user is connected and disconnect the user if a connected.
        /// When the user logs in, according to its user level data is loaded and screens are enabled for use
        /// </summary>
        private void LoginButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.ConnectedUser != null)
            {
                MessageBox.Show("User Disconnected");
                this.LoginButton.Content = LoginButtonStatus.Connect.ToString();
                this.ConnectedUser = null;
                this.RegisterButton.IsEnabled = false;
                this.AddEdditDeleteButonsCanvas.Visibility = Visibility.Collapsed;
                this.IssueDataGrid.ItemsSource = null;

            }
            else
            {
                this.ConnectedUser = this.serviceClient.Login(this.LoginTextBox.Text, this.PasswordTextBox.Password);

                if (this.ConnectedUser != null)
                {
                    MessageBox.Show(String.Format("{0} Connected", this.LoginTextBox.Text));
                    //TODO: Change this to Observable Collection
                    this.LoginButton.Content = LoginButtonStatus.Disconnect.ToString();
                    this.AddEdditDeleteButonsCanvas.Visibility = Visibility.Visible;

                    //Check if admin and enable add new user and assign issue to users.
                    if (this.connectedUser.PrivilidgeLevel == PrivilidgeCondition.Administrator)
                    {
                        RegisterButton.Visibility = Visibility.Visible;
                        this.RegisterButton.IsEnabled = true;
                    }
                    else
                        RegisterButton.Visibility = Visibility.Hidden;
                    
                    this.IssueDataGrid.ItemsSource = this.issueList;
                    this.AddButton.IsEnabled = true;
                    this.LoadData();
                }
                else
                    MessageBox.Show("Incorrect user name or password");
            }
            
            //this.RegisterButton.IsEnabled = (ConnectedUser == null);
        }

        /// <summary>
        /// Button fired when user clicks on register button. This will add a user to the users list.
        /// </summary>
        private void RegisterButton_Click(object sender, RoutedEventArgs e)
        {
            UserEdit myEdit = new UserEdit();
            myEdit.Owner = this;
            myEdit.ShowDialog();

            if (myEdit.DialogResult == true)
            {
                this.serviceClient.AddUser(myEdit.DataContext as User);
                MessageBox.Show("User Added");
            }
        }

        #endregion

        #region Issue-List-Controls

        /// <summary>
        /// Method fired to add a new Issue. The method will create an empty issue as the data context of the issue details grid so it can edited.
        /// It will also change the edit button from the issue detail grid to display "create"
        /// </summary>
        private void AddEditButton_Click(object sender, RoutedEventArgs e)
        {
            IssueWindow issueWindow = new IssueWindow();
            issueWindow.Owner = this;
            
            string message = string.Empty;

            Button mySender = (Button)sender;
            if (mySender.Content.Equals("Edit"))
            {
                issueWindow.DataContext = this.IssueDataGrid.SelectedItem;
                message = "Edited";
            }
            else
                message = "Added";

            if (this.ConnectedUser.PrivilidgeLevel == PrivilidgeCondition.Administrator)
                issueWindow.IssueAssignToComboBox.ItemsSource = this.serviceClient.GetAllUsers();
            else
                issueWindow.IssueAssignToComboBox.Items.Add(this.ConnectedUser);

            issueWindow.IssueStatusComboBox.ItemsSource = Enum.GetValues(typeof(Status));
            
            issueWindow.ShowDialog();
            
            if (issueWindow.DialogResult == true)
            {
                Issue tempIssue = issueWindow.DataContext as Issue;

                if (mySender.Content.Equals("Edit"))
                    serviceClient.EditIssue(tempIssue);
                else
                {
                    //tempIssue.IssueId = serviceClient.GetNextID().ToString();
                    this.serviceClient.AddIssue(tempIssue);
                }

                MessageBox.Show(String.Format("Issue {0}", message));
                this.LoadData();
            }
            
        }

        /// <summary>
        /// Method fired when a selection is made on the issue listbox. It is used to enable the edit button ONLY when an item is selected.
        /// </summary>
        private void IssueDataGrid_SelectedCellsChanged(object sender, Microsoft.Windows.Controls.SelectedCellsChangedEventArgs e)
        {
            this.EditButton.IsEnabled = (this.IssueDataGrid.SelectedItem != null);
        }

        #endregion

        #region helper methods

        /// <summary>
        /// Static method used to convert an array to an Observable Collection. This collection can be bound as the data context to a control and there is no need to implement inotify interface to display changes
        /// </summary>
        /// <typeparam name="T">Type of the object that will be copied to the collection</typeparam>
        /// <param name="list">the array with the objects to be copied</param>
        /// <returns>An observable collection with objects inside</returns>
        public static ObservableCollection<T> ConvertArrayToObservableCollection<T>(T[] list)
        {
            ObservableCollection<T> myGenericList = new ObservableCollection<T>();
            foreach (T temp in list)
            {
                myGenericList.Add(temp);
            }

            return myGenericList;
        }

        private void LoadData()
        {
            if (ConnectedUser.PrivilidgeLevel == PrivilidgeCondition.Administrator)
            {
                this.IssueDataGrid.ItemsSource = Window1.ConvertArrayToObservableCollection<Issue>(this.serviceClient.GetAllIssues());
            }
            else
            {
                this.IssueDataGrid.ItemsSource = Window1.ConvertArrayToObservableCollection<Issue>(this.serviceClient.GetIssuesFor(this.ConnectedUser));
            }
        }

        #endregion

        private void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            if (this.ConnectedUser.PrivilidgeLevel == PrivilidgeCondition.Administrator)
            {
                 if (IssueDataGrid.SelectedItem != null)
                 {
                     Issue i = (Issue)IssueDataGrid.SelectedItem;
                     this.serviceClient.RemoveIssue(i);
                     this.LoadData();
                 }

            }
            else
                MessageBox.Show("Must be an Administrator!");
        }

        

    }
}
